<template>
  <el-breadcrumb class = "app-breadcrumb breadcrumb-container" separator = "/">
    <el-breadcrumb-item
        v-for = "(item, index) in levelList"
        :key = "item.path"
    >
      <!-- 面包屑导航最后一个是不可点击的 因为最后一个正是当前所显示的路由 -->
      <span
          v-if = "index == levelList.length - 1"
          class = "no-redirect"
      >
          {{ item.meta.title }}
      </span>
      <a v-else @click.prevent = "handleLink(item)">{{ item.meta.title }}</a>
    </el-breadcrumb-item>
  </el-breadcrumb>
</template>

<script lang = "ts">
import { defineComponent, ref, onBeforeMount, watch } from 'vue'
import { RouteLocationMatched, useRoute, useRouter, RouteLocationRaw } from 'vue-router'
import { compile } from 'path-to-regexp'

type PartialRouteLocationMatched = Partial<RouteLocationMatched>

export default defineComponent({
  name: 'Breadcrumb',
  setup() {
    const route = useRoute(),
        router = useRouter(),
        levelList = ref<Array<PartialRouteLocationMatched>>([])

    /* 判断路由是否是Dashboard路由 */
    const isDashboard = (route?: PartialRouteLocationMatched) => {
      const name = route && route.name
      if ( !name ) return false
      return (name as string).trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
    }

    /* 获取面包屑导航 */
    const getBreadcrumb = () => {
      /* 对匹配的路由进行过滤 如果没有title 无法用title作为面包屑 */
      let matched = route.matched.filter(item => item.meta && item.meta.title) as PartialRouteLocationMatched[]
      const first = matched[0]
      if ( !isDashboard(first) ) {
        matched = ([ {
          path: '/dashboard',
          meta: { title: 'Dashboard' }
        } ] as PartialRouteLocationMatched[]).concat(matched)
      }
      levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
    }

    onBeforeMount(() => {
      getBreadcrumb()
    })

    watch(() => route.path, () => getBreadcrumb())

    /* 主要是针对动态路由 进行动态参数填充 */
    const pathCompile = (path: string) => {
      const toPath = compile(path),
          params = route.params
      return toPath(params)
    }

    /* 点击面包屑可以跳转 */
    const handleLink = (route: RouteLocationMatched) => {
      const { path, redirect } = route
      if ( redirect ) {
        router.push(redirect as RouteLocationRaw)
        return
      }
      router.push(pathCompile(path))
    }

    return {
      levelList,
      handleLink
    }
  }
})
</script>

<style lang = "scss" scoped>
.app-breadcrumb.el-breadcrumb {
  display: inline-block;
  line-height: 50px;
  font-size: 14px;
  margin-left: 8px;
}

.no-redirect {
  color: #97a8be;
  cursor: text;
}
</style>


<style lang = "scss">
.breadcrumb-enter-active,
.breadcrumb-leave-active {
  transition: all .5s;
}

.breadcrumb-enter,
.breadcrumb-leave-active {
  opacity: 0;
  transform: translateX(20px);
}


.breadcrumb-leave-active {
  position: absolute;
}

.breadcrumb-move {
  transition: all .5s;
}
</style>
